package org.alfalfa.web;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mongodb.client.model.Filters;
import messages.Login;
import org.alfalfa.component.APInstance;
import org.alfalfa.datacenter.ThreadPoolCenter;
import org.alfalfa.datawarehouse.DWHook;
import org.alfalfa.datawarehouse.DWManager;
import org.alfalfa.datawarehouse.DWResultset;
import org.alfalfa.datawarehouse.model.Account;
import org.alfalfa.datawarehouse.model.User;
import org.alfalfa.utils.AppUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.Enumeration;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Author : Max-Goday
 * @Created : 2016-10-21
 * @E-mail : goday.max@gmail.com
 * @Version : 1.0
 */
@RestController
@RequestMapping("/api")
public class ApiController {

	private static ExecutorService ESPOOL = Executors.newFixedThreadPool(100);


	@RequestMapping("/start")
	public Object start(HttpServletRequest request, @RequestParam String loginData,
						@RequestParam String accountId, @RequestParam String passToken,
						@RequestParam String name) {

		Login login = null;

		if (StringUtils.isNoneBlank(loginData)) {
			login = new Login(common.StringUtils.stringToByteArray(loginData));
		} else {
			login = AppUtils.getFarmWithIdAndToken(null, null, Long.parseLong(accountId), passToken);
		}

//		String loginRaw = "0000000500ff542800000028633364676b6a7434336a7237797934703762776177346278796b7a6d726439396b6a6b67346b32620000002864616462623264643939626134376336303237323634396466346263336362613334306462333863001074600000000000000010636562336235323631313262646339650000001130383a30303a32373a32333a36313a65320000000e536f6e7920587065726961205a320000002439613463623266302d383861622d336263372d616461332d3432633439636564393265380100000003342e3400000000000000106365623362353236313132626463396500000002454e00000000010000000000000002";

		APInstance apins = new APInstance(login, null, name);

		//check if exsit
		APInstance exsit = ThreadPoolCenter.getApByKey(request.getSession().getAttribute("userLoginId") + "_" + name);
		if (exsit != null) {
			try {
				Thread apThr = (Thread) getApThr(exsit);
				apThr.interrupt();
			} catch (Exception e){}
		}

		ESPOOL.submit(apins.ap);
		ThreadPoolCenter.putApThread(request.getSession().getAttribute("userLoginId") + "_" + name, apins);

		return getMsg(true, null);
	}

	private Object getApThr(APInstance apInstance) {
		try {
			Field field = Class.forName("common.AccountProcess").getDeclaredField("thr");
			field.setAccessible(true);
			return field.get(apInstance.ap);

		} catch (Exception e){
			return null;
		}
	}

	@RequestMapping("/getData")
	public Object getData(HttpServletRequest request, @RequestParam String name) {

		APInstance apins = ThreadPoolCenter.getApByKey(request.getSession().getAttribute("userLoginId") + "_" + name);
		if (apins == null || apins.farm == null) return new JSONObject();

		return apins.farm.getGOODS() == null ? new JSONObject() : apins.farm.getGOODS();

	}


	@RequestMapping("/getAll")
	public Object getAll(HttpServletRequest request) {
		Enumeration<String> keys = ThreadPoolCenter.getTmapKeySet();

		//init all account
		DWHook hook = DWManager.getHook(ThreadPoolCenter.ACCOUNT_SCOPE);
		DWResultset result = hook.find(Filters.eq("user", (String) request.getSession().getAttribute("userLoginId")));

		while (result.next()) {
			JSONObject item = result.get().getAsJSON();

			Login login = null;

			if (StringUtils.isNoneBlank(item.getString("loginData"))) {
				login = new Login(common.StringUtils.stringToByteArray(item.getString("loginData")));
			} else {
				login = AppUtils.getFarmWithIdAndToken(null, null, Long.parseLong(item.getString("accountId")), item.getString("passToken"));
			}

			APInstance apins = new APInstance(login, null, item.getString("name"));

			//check if exsit
			APInstance exsit = ThreadPoolCenter.getApByKey(request.getSession().getAttribute("userLoginId") + "_" + item.getString("name"));
			if (exsit == null) {
				ESPOOL.submit(apins.ap);
				ThreadPoolCenter.putApThread(request.getSession().getAttribute("userLoginId") + "_" + item.getString("name"), apins);
			}
		}


		JSONArray arr = new JSONArray();

		while (keys.hasMoreElements()) {
			String k = keys.nextElement();

			if (k.startsWith((String) request.getSession().getAttribute("userLoginId"))) {
				try {
					arr.add(ThreadPoolCenter.getApByKey(k).farm.getGOODS());
				} catch (Exception e){}
			}
		}

		return arr;
	}


	@RequestMapping("/create")
	public Object create(HttpServletRequest request) {

		String farm_name = request.getParameter("farm_name");
		String account_id = request.getParameter("account_id");
		String pass_token = request.getParameter("pass_token");
		String login_data = request.getParameter("login_data");

		if (StringUtils.isBlank(login_data) && (StringUtils.isBlank(account_id) || StringUtils.isBlank(pass_token)))
			return getMsg(false, "账号信息不正确!");

		DWHook hook = DWManager.getHook(ThreadPoolCenter.ACCOUNT_SCOPE);
		DWResultset result = null;

		if (StringUtils.isBlank(login_data)) {
			result = hook.find(Filters.and(Filters.eq("passToken", pass_token),
					Filters.eq("accountId", account_id)));
		} else {
			result = hook.find(Filters.eq("loginData", login_data));
		}

		if (result.next()) {
			return getMsg(false, "该农场已经存在!");
		}

		Account account = hook.newRecord(Account.class);
		account.setAccountId(account_id);
		account.setPassToken(pass_token);
		account.setName(farm_name);
		account.setUser((String) request.getSession().getAttribute("userLoginId"));
		account.setLoginData(login_data);

		account.save();

		return getMsg(true, null);
	}

	@RequestMapping("/login")
	public Object login(HttpServletRequest request) {

		String username = request.getParameter("username");
		String password = request.getParameter("password");

		DWHook hook = DWManager.getHook(ThreadPoolCenter.USER_SCOPE);

		DWResultset result = hook.find(Filters.and(Filters.eq("name", username), Filters.eq("password", password)));

		if (result.next()) {
			request.getSession().setAttribute("userLoginId", username);
		}

		return getMsg(true, null);
	}

	@RequestMapping("/login/backdoor")
	public Object backdoor(HttpServletRequest request) {

		String username = request.getParameter("username");
		String password = request.getParameter("password");

		DWHook hook = DWManager.getHook(ThreadPoolCenter.USER_SCOPE);
		User user = hook.newRecord(User.class);

		user.setName(username);
		user.setPassword(password);

		user.save();

		return getMsg(true, null);
	}


	private JSONObject getMsg(boolean success, String msg) {

		JSONObject r = new JSONObject();

		r.put("success", success);
		r.put("msg", msg);

		return r;

	}
}
